package com.guguskins.back.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guguskins.back.common.constant.InventoryConstant;
import com.guguskins.back.common.constant.PrizeType;
import com.guguskins.back.common.constant.RecordConstant;
import com.guguskins.back.common.exception.GlobalMsgException;
import com.guguskins.back.entity.*;
import com.guguskins.back.entity.vo.LevelPrizeVo;
import com.guguskins.back.mapper.GuUserLevelMapper;
import com.guguskins.back.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author mybatis-plus
 * @since 2021-06-15
 */
@Service
public class GuUserLevelServiceImpl extends ServiceImpl<GuUserLevelMapper, GuUserLevel> implements GuUserLevelService {
    @Autowired
    private GuUserLevelMapper userLevelMapper;
    @Autowired
    private GuBoxService boxService;

    @Autowired
    private GuPropService propService;

    @Autowired
    private GuRecordService recordService;

    @Autowired
    private GuUserService userService;

    @Autowired
    private GuInventoryService inventoryService;

    @Autowired
    private GuPropNumService propNumService;

    @Autowired
    private GuGoodsService goodsService;


    @Override
    public List<Map<String, Object>> showListMap(Long userId) {

        GuUser user = userService.getById(userId);

        List<GuUserLevel> userLevelList = this.list(new LambdaQueryWrapper<GuUserLevel>() {
            {
                select(GuUserLevel::getUlId, GuUserLevel::getUlName, GuUserLevel::getUlValue, GuUserLevel::getUlExperience, GuUserLevel::getUlPrizeType, GuUserLevel::getUlPrizeId);
                orderByAsc(GuUserLevel::getUlValue);
            }
        });
        List<GuRecord> records = recordService.list(new LambdaQueryWrapper<GuRecord>() {
            {
                eq(GuRecord::getRecordUserId, user.getUserId());
                eq(GuRecord::getRecordSourceType, InventoryConstant.Source.USER_LEVEL_REWARD);
            }
        });
        //初始化数据
        userLevelList.forEach(userLevel -> {
            if (!ObjectUtils.isEmpty(userLevel.getUlPrizeType()) && !ObjectUtils.isEmpty(userLevel.getUlPrizeId())) {
                switch (userLevel.getUlPrizeType()) {
                    case PrizeType.BOX:
                        GuBox box = boxService.getBox(userLevel.getUlPrizeId());
                        userLevel.setPrizeImage(box.getBoxImageUrl());
                        userLevel.setPrizeGoodsImage(box.getGoodsList().stream().max(Comparator.comparing(GuGoods::getGoodsPrice)).orElse(new GuGoods()).getGoodsIconUrl());
                        break;
                    case PrizeType.GOODS:
                        GuGoods goods = goodsService.getById(userLevel.getUlPrizeId());
                        userLevel.setPrizeImage(goods.getGoodsIconUrl());
                        break;
                    case PrizeType.PROP:
                        GuProp prop = propService.getById(userLevel.getUlPrizeId());
                        userLevel.setPrizeImage(prop.getPropImage());
                        break;
                    default:
                        break;
//                        throw new GlobalMsgException("系统错误");
                }
                if (userLevel.getUlExperience().compareTo(user.getUserLevelExperience()) <= 0) {
                    userLevel.setPrizeState(records.stream().anyMatch(record -> Long.valueOf(userLevel.getUlId()).equals(record.getRecordSourceId())) ? 2 : 1);
                } else {
                    userLevel.setPrizeState(0);
                }
            }
            if (userLevel.getUlExperience().compareTo(user.getUserLevelExperience()) <= 0) {
                userLevel.setState(1);
            } else {
                userLevel.setState(0);
            }

        });
        //处理奖品领取未领取
        return this.partitionGuUserLevelMap(userLevelList, 6);
    }

    @Override
    public LevelPrizeVo receivePrize(Long userId, Integer ulId) {
        LevelPrizeVo levelPrizeVo = new LevelPrizeVo();
        GuUser user = userService.getById(userId);

        GuUserLevel userLevel = this.getById(ulId);
        levelPrizeVo.setUserLevel(userLevel.getUlValue());
        GuInventory inventory;
        switch (userLevel.getUlPrizeType()) {
            case PrizeType.BOX:
//                GuBox box = boxService.getBox(inviteNum.getInvitePrizeId());
                //添加库存
                inventory = inventoryService.addInventory(user.getUserId(), user.getUserSteamId(), InventoryConstant.Type.BOX, InventoryConstant.Source.USER_LEVEL_REWARD, Long.valueOf(userLevel.getUlId()), userLevel.getUlPrizeId(), null);
                recordService.addRecord(user.getUserId(), RecordConstant.TYPE.GAIN, InventoryConstant.Source.USER_LEVEL_REWARD, userLevel.getUlId(), PrizeType.BOX, userLevel.getUlPrizeId(), "等级奖励领取奖品", userLevel.getUlId().toString());
                levelPrizeVo.setItemLevel(5);
                GuBox box = boxService.getBox(inventory.getInventoryItemId());
                levelPrizeVo.setItemImage(box.getBoxImageUrl());
                levelPrizeVo.setItemSubImage(box.getGoodsList().stream().max(Comparator.comparing(GuGoods::getGoodsPrice)).orElse(new GuGoods()).getGoodsIconUrl());
                levelPrizeVo.setItemName(box.getBoxName());
                levelPrizeVo.setItemPrice(box.getBoxPrice());
                break;
            case PrizeType.GOODS:
                //添加库存
                inventory = inventoryService.addInventory(user.getUserId(), user.getUserSteamId(), InventoryConstant.Type.GOODS, InventoryConstant.Source.USER_LEVEL_REWARD, Long.valueOf(userLevel.getUlId()), userLevel.getUlPrizeId(), null);
                recordService.addRecord(user.getUserId(), RecordConstant.TYPE.GAIN, InventoryConstant.Source.USER_LEVEL_REWARD, userLevel.getUlId(), PrizeType.BOX, userLevel.getUlPrizeId(), "等级奖励领取奖品", userLevel.getUlId().toString());
                levelPrizeVo.setItemLevel(5);
                GuGoods goods = goodsService.getById(inventory.getInventoryItemId());
                levelPrizeVo.setItemImage(goods.getGoodsIconUrl());
                levelPrizeVo.setItemName(goods.getGoodsName());
                levelPrizeVo.setItemPrice(goods.getGoodsPrice());
                break;
            case PrizeType.PROP:
                propNumService.addPropNum(userId, userLevel.getUlPrizeId());
                recordService.addRecord(user.getUserId(), RecordConstant.TYPE.GAIN, InventoryConstant.Source.USER_LEVEL_REWARD, userLevel.getUlId(), PrizeType.PROP, userLevel.getUlPrizeId(), "等级奖励领取奖品", userLevel.getUlId().toString());
                GuProp prop = propService.getById(userLevel.getUlPrizeId());
                levelPrizeVo.setItemImage(prop.getPropImage());
                levelPrizeVo.setItemName(prop.getPropName());
                break;
            default:
                throw new GlobalMsgException("参数错误");
        }
        return levelPrizeVo;
    }

    @Override
    public List<GuUserLevel> backList() {
        List<GuUserLevel> userLevels = userLevelMapper.selectList(new LambdaQueryWrapper<GuUserLevel>() {
            {
                orderByAsc(GuUserLevel::getUlValue);
            }
        });
        userLevels.forEach(guUserLevel ->
                {
                    if (guUserLevel.getUlPrizeType() != null) {
                        if (guUserLevel.getUlPrizeType() == 1) {
                        GuBox box= boxService.getById(guUserLevel.getUlPrizeId());
                            guUserLevel.setItemName(box.getBoxName());
                            guUserLevel.setItemImages(box.getBoxImageUrl());
                        } else if (guUserLevel.getUlPrizeType() == 2) {
                            GuGoods guGoods=goodsService.getById(guUserLevel.getUlPrizeId());
                            guUserLevel.setItemName(guGoods.getGoodsName());
                            guUserLevel.setItemImages(guGoods.getUserImage());
                        } else if(guUserLevel.getUlPrizeType()==3) {
                          GuProp prop=  propService.getById(guUserLevel.getUlPrizeId());
                            guUserLevel.setItemName(prop.getPropName());
                            guUserLevel.setItemImages(prop.getPropImage());
                        }

                    }

                }
        );
        return userLevels;
    }

    @Override
    public int insert(GuUserLevel userLevel)
    {
    Integer max=  userLevelMapper.getMax();
      if(userLevel!=null&&userLevel.getUlValue()>max) {
          if (userLevel.getUlValue() >= max + 1 ) {
              BigDecimal eMax = userLevelMapper.getExperience(max);
              if (userLevel.getUlExperience() != null && userLevel.getUlExperience().compareTo(eMax) > 0) {

                  userLevelMapper.insert(userLevel);
                  return 0;
              }
              return 1;
          } else {
              return 2;
          }
      }else {
          return 3;
      }

    }



    private List<Map<String, Object>> partitionGuUserLevelMap(final List<GuUserLevel> list, final int size) {
        int limit = (list.size() + size - 1) / size;
        List<Map<String, Object>> mglist = new ArrayList<>();
        Stream.iterate(0, n -> n + 1).limit(limit).forEach(i -> {
            Map<String, Object> map = new HashMap<>();
            List<GuUserLevel> userLevelSubList = list.stream().skip((long) i * size).limit(size).collect(Collectors.toList());
            map.put("children", userLevelSubList);
            map.put("min", userLevelSubList.stream().map(GuUserLevel::getUlValue).reduce(Integer::min).orElse(0));
            map.put("max", userLevelSubList.stream().map(GuUserLevel::getUlValue).reduce(Integer::max).orElse(5));
            mglist.add(map);
        });
        return mglist;
    }
}
